package hms.master;

import hms.FrontDeskModule.*;
import hms.HotelAdministrationModule.*;
import hms.ReservationsModule.*;
import hms.RoomManagementModule.*;
import hms.UserAccountsModule.*;
import hms.employees.*;
import hms.generic.AbstractGlobalView;
import hms.permissions.Permission;
import hms.properties.Properties;

import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;

/**
 * <h2>Class Overview</h2> 
 * This class is responsible for displaying and controlling the initial screen of the
 * HMS and then creating the subviews to populate the Modules, etc.
 * TODO [matt] FINISH THESE COMMENTS
 * @author Matthew Johnson
 */


public class MasterView extends AbstractGlobalView implements MouseListener{
	
	// Popup Menu for right-clicking each module
	JPopupMenu reservationPopup;
	JPopupMenu frontDeskPopup;
	JPopupMenu roomManagementPopup;
	JPopupMenu userAccountPopup;
	JPopupMenu hotelAdminPopup;
	
	// To see if login failed
	boolean failedLogin;
	
	// TODO [matt] Finish adding comments
	// TODO [matt] Add in the rest of the GUI elements
	public MasterView(){
		
		// Initialize popup menu
		reservationPopup = new JPopupMenu();
		frontDeskPopup = new JPopupMenu();
		roomManagementPopup = new JPopupMenu();
		userAccountPopup = new JPopupMenu();
		hotelAdminPopup = new JPopupMenu();
		
		// Populate popup menus
		populatePopupMenus();
		JPanel mainPanel = new JPanel();
		
		String strHMSLogo = "<html><div style=\"background-color:#CFAC1F; vertical-align: middle;\"><h1 style=\"text-align: center\">"
				+ "<span style=\"font-family: Arial, Helvetica, sans-serif;\">H<span style=\"font-size: large; font-style: italic; "
				+ "font-family: Arial, Helvetica, sans-serif;\">OTEL</span><br /><span style=\"font-family: Arial, Helvetica, "
				+ "sans-serif;\">M<span style=\"font-size: large; font-style: italic; font-family: Arial, Helvetica, sans-serif;\">"
				+ "ANAGEMENT</span><br /><span style=\"font-family: Arial, Helvetica, sans-serif;\">S<span style=\"font-size: large; "
				+ "font-style: italic; font-family: Arial, Helvetica, sans-serif;\">YSTEM</span></h1><div style=\"background-color: "
				+"#E0C962; padding-right: 50px;  padding-left: 50px;\"><h2>Team MAYBE</h2><p>Matt Johnson<br />Akilah McIntyre<br />"
				+"Yifeng Zou<br />Ben Adcock<br />Edgar Onukwugha<br /></p><p>&nbsp;</p><p>&nbsp;</p></div></div></html>";
		mainPanel.add(new JLabel(strHMSLogo));
		// Create blank initial display
		// TODO [matt] Add splash screen here again
		super.initialize(mainPanel, this);
		super.display();
	}
	
	/**
	 * Populate the corresponding Popup menus with the associated menu items required
	 */
	private void populatePopupMenus(){
		
		// Create menu items for reservationPopup
		JMenuItem menuItem_CheckIn = new JMenuItem("Check-In");
		//JMenuItem menuItem_Rewards = new JMenuItem("Rewards");
		JMenuItem menuItem_GuestInfo = new JMenuItem("Guest Information");
		// Set action listeners
		menuItem_CheckIn.setActionCommand("menuItem_CheckIn");
		menuItem_CheckIn.addActionListener( this );
		//menuItem_Rewards.setActionCommand("menuItem_Rewards");
		//menuItem_Rewards.addActionListener( this );
		menuItem_GuestInfo.setActionCommand("menuItem_GuestInfo");
		menuItem_GuestInfo.addActionListener( this );
		// Add to popup menu
		reservationPopup.add(menuItem_CheckIn);
		//reservationPopup.add(menuItem_Rewards);
		reservationPopup.add(menuItem_GuestInfo);
		
		// Create menu items for frontDeskPopup
		JMenuItem menuItem_Checkout = new JMenuItem("Check-Out");
		JMenuItem menuItem_GuestServices = new JMenuItem("Guest Services");
		JMenuItem menuItem_RoomServices = new JMenuItem("Room Services");
		// Set action listeners
		menuItem_Checkout.setActionCommand("menuItem_Checkout");
		menuItem_Checkout.addActionListener( this );
		menuItem_GuestServices.setActionCommand("menuItem_GuestServices");
		menuItem_GuestServices.addActionListener( this );
		menuItem_RoomServices.setActionCommand("menuItem_RoomServices");
		menuItem_RoomServices.addActionListener( this );
		// Add to popup menu
		frontDeskPopup.add(menuItem_Checkout);
		frontDeskPopup.add(menuItem_GuestServices);
		frontDeskPopup.add(menuItem_RoomServices);		
		
		// Create menu items for roomManagementPopup
		JMenuItem menuItem_ManageRooms = new JMenuItem("Manage/View Rooms");
		JMenuItem menuItem_ConfigureRooms = new JMenuItem("Configure Rooms");
		// Set action listeners
		menuItem_ManageRooms.setActionCommand("menuItem_ManageRooms");
		menuItem_ManageRooms.addActionListener( this );
		menuItem_ConfigureRooms.setActionCommand("menuItem_ConfigureRooms");
		menuItem_ConfigureRooms.addActionListener( this );
		// Add to popup menu
		roomManagementPopup.add(menuItem_ManageRooms);
		roomManagementPopup.add(menuItem_ConfigureRooms);
		
		// Create menu items for hotelAdminPopup
		JMenuItem menuItem_Inventory = new JMenuItem("Inventory");
		//JMenuItem menuItem_ScheduleEmployeeShifts = new JMenuItem("Schedule Employee Shifts");
		//JMenuItem menuItem_GenerateRoomReports = new JMenuItem("Generate Room Reports");
		JMenuItem menuItem_GenerateShiftReports = new JMenuItem("Generate Reports");
		JMenuItem menuItem_ManageEmployees = new JMenuItem("Manage Employees");
		// Set action listeners
		menuItem_Inventory.setActionCommand("menuItem_Inventory");
		menuItem_Inventory.addActionListener( this );
	//	menuItem_ScheduleEmployeeShifts.setActionCommand("menuItem_ScheduleEmployeeShifts");
		//menuItem_ScheduleEmployeeShifts.addActionListener( this );
		//menuItem_GenerateRoomReports.setActionCommand("menuItem_GenerateRoomReports");
		//menuItem_GenerateRoomReports.addActionListener( this );
		menuItem_GenerateShiftReports.setActionCommand("menuItem_GenerateShiftReports");
		menuItem_GenerateShiftReports.addActionListener( this );
		menuItem_ManageEmployees.setActionCommand("menuItem_ManageEmployees");
		menuItem_ManageEmployees.addActionListener( this );
		// Add to popup menu
		hotelAdminPopup.add(menuItem_Inventory);
		//hotelAdminPopup.add(menuItem_ScheduleEmployeeShifts);
//		hotelAdminPopup.add(menuItem_GenerateRoomReports);
		hotelAdminPopup.add(menuItem_GenerateShiftReports);
		hotelAdminPopup.add(menuItem_ManageEmployees);
		
		// Create menu items for userAccountsPopup
		JMenuItem menuItem_UserAccounts = new JMenuItem("User Accounts");
		//Set action listeners
		menuItem_UserAccounts.setActionCommand("menuItem_UserAccounts");
		menuItem_UserAccounts.addActionListener( this );
		// Add to popup menu
		userAccountPopup.add(menuItem_UserAccounts);
	}
	
	/**
	 * This is an overridden method that is required of all Views to handle any input events
	 * that occur on the main window such as the menu bar and the modules. This is the main
	 * View which controls creating all other views. 
	 */
	@SuppressWarnings("unused")
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO [matt] Put in switch statement to handle the events that can occur here in the file menu
		
		// If Exit button is clicked in File menu
		if(e.getActionCommand().equalsIgnoreCase("menuItem_exit")){
			
			// Options for buttons
			Object[] options = {"Yes", "Cancel"};
			
			// Show popup to confirm system exit and store response
			int response = JOptionPane.showOptionDialog(null, 
					"Are you sure you want to exit?",
					"Exit HMS",
					JOptionPane.OK_CANCEL_OPTION,
					JOptionPane.PLAIN_MESSAGE,
					null,
					options,
					options[0]);
			
			// If the yes option was clicked, exit the program
			if(response == JOptionPane.YES_OPTION){
				MasterController.closeDatabaseConnection();
				System.exit(0);
			}
			
		}
		
		// If Login button is clicked in File menu
		if(e.getActionCommand().equalsIgnoreCase("menuItem_login")){
			
			// Call method for handling login logic
			createLoginDialog();
		}
		
			
		// If Check-Out menu item is selected from popup menu
		if(e.getActionCommand().equalsIgnoreCase("menuItem_CheckIn")
				&& assertPermissionGranted(Permission.CHECK_IN_OUT)
				&& assertPermissionGranted(Permission.RESERVE_ROOMS)){
			if(Properties.isLoggedIn){
				if(displayInformationWillBeLostDialog()){
					super.destroy();
					Properties.currentView = "CheckInView";
					//ReservationModule reservationModule = new ReservationModule((new CheckInView()).createCheckInView());
					CheckInView cv = new CheckInView();
				}
			}
			else
				displayNotLoggedInAlert();
		}
		// If Check-Out menu item is selected from popup menu
		if(e.getActionCommand().equalsIgnoreCase("menuItem_Rewards")
				&& assertPermissionGranted(Permission.CHECK_IN_OUT)
				&& assertPermissionGranted(Permission.OFFER_ADDITIONAL_GUEST_SERVICES)
				&& assertPermissionGranted(Permission.RESERVE_ROOMS)){
			if(Properties.isLoggedIn){
				if(displayInformationWillBeLostDialog()){
					super.destroy();
					Properties.currentView = "RewardsView";
					RewardsView rewardsView = new RewardsView();
				}
			}
			else
				displayNotLoggedInAlert();
		}
		// If Check-Out menu item is selected from popup menu
		if(e.getActionCommand().equalsIgnoreCase("menuItem_GuestInfo")){
			if(Properties.isLoggedIn){
				if(displayInformationWillBeLostDialog()){
					super.destroy();
					Properties.currentView = "GuestInfoView";
					//ReservationModule reservationModule = new ReservationModule((new GuestInfoView()).initGuestInfoView());
					GuestInformationView gview = new GuestInformationView();
				}
			}
			else
				displayNotLoggedInAlert();
		}
		// If Check-Out menu item is selected from popup menu
		if(e.getActionCommand().equalsIgnoreCase("menuItem_CheckOut")
				&& assertPermissionGranted(Permission.CHECK_IN_OUT)){
			if(Properties.isLoggedIn){
				if(displayInformationWillBeLostDialog()){
					super.destroy();
					Properties.currentView = "CheckOutView";
					CheckOutView checkOutView = new CheckOutView();
				}
			}
			else
				displayNotLoggedInAlert();
		}
		// If Check-Out menu item is selected from popup menu
		if(e.getActionCommand().equalsIgnoreCase("menuItem_GuestServices")){
			if(Properties.isLoggedIn){
				if(displayInformationWillBeLostDialog()){
					super.destroy();
					Properties.currentView = "GuestServicesView";
					GuestServicesView guestServicesView = new GuestServicesView();
				}
			}
			else
				displayNotLoggedInAlert();
		}
		// If Check-Out menu item is selected from popup menu
		if(e.getActionCommand().equalsIgnoreCase("menuItem_RoomServices")
				&& assertPermissionGranted(Permission.OFFER_ADDITIONAL_GUEST_SERVICES)){
			if(Properties.isLoggedIn){
				if(displayInformationWillBeLostDialog()){
					super.destroy();
					Properties.currentView = "RoomServicesView";
					RoomServicesView roomServicesView = new RoomServicesView();
				}
			}
			else
				displayNotLoggedInAlert();
		}
		
		// If Manage Rooms menu item is selected from popup menu
		if(e.getActionCommand().equalsIgnoreCase("menuItem_ManageRooms")){	
			if(Properties.isLoggedIn){
				if(displayInformationWillBeLostDialog()){
					super.destroy();
					Properties.currentView = "ManageRoomsView";
					ManageRoomsView manageRoomsView = new ManageRoomsView();
				}
			}
			else if(!Properties.isLoggedIn)
				displayNotLoggedInAlert();
		}
		
		// If Configure Rooms menu item is selected from popup menu
		if(e.getActionCommand().equalsIgnoreCase("menuItem_ConfigureRooms")
				&& assertPermissionGranted(Permission.CONFIGURE_ROOMS)){
			if(Properties.isLoggedIn){
				if(displayInformationWillBeLostDialog()){
					super.destroy();
					Properties.currentView = "ConfigureRoomsView";
					ConfigureRoomsView configureRoomsView = new ConfigureRoomsView();
				}
			}
			else if(!Properties.isLoggedIn)
				displayNotLoggedInAlert();
		}
		
		// If Inventory menu item is selected from popup menu
		if(e.getActionCommand().equalsIgnoreCase("menuItem_Inventory")
				&& assertPermissionGranted(Permission.MANAGE_INVENTORY)){
			if(Properties.isLoggedIn){
				if(displayInformationWillBeLostDialog()){
					super.destroy();
					Properties.currentView = "ManageInventoryView";
					ManageInventoryView manageInventoryView = new ManageInventoryView();
				}
			}
			else
				displayNotLoggedInAlert();
		}
		// If Inventory menu item is selected from popup menu
		/*if(e.getActionCommand().equalsIgnoreCase("menuItem_ScheduleEmployeeShifts")){
			if(Properties.isLoggedIn){
				if(displayInformationWillBeLostDialog()){
					super.destroy();
					Properties.currentView = "ScheduleEmployeeShiftView";
					ScheduleEmployeeShiftView scheduleEmployeeShiftView = new ScheduleEmployeeShiftView();
				}
			}
			else
				displayNotLoggedInAlert();
		}
		*/
		// If Inventory menu item is selected from popup menu
		/*if(e.getActionCommand().equalsIgnoreCase("menuItem_GenerateRoomReports")){
			if(Properties.isLoggedIn){
				if(displayInformationWillBeLostDialog()){
					super.destroy();
					Properties.currentView = "GenerateRmSchedRptView";
					GenerateRmSchedRptView generateRmSchedRptView = new GenerateRmSchedRptView();
				}
			}
			else
				displayNotLoggedInAlert();

		}
		*/
		// If Generate Shift Reports menu item is selected from popup menu
		if(e.getActionCommand().equalsIgnoreCase("menuItem_GenerateShiftReports")
				&& assertPermissionGranted(Permission.REPORT_BUILDER)){
			if(Properties.isLoggedIn){
				if(displayInformationWillBeLostDialog()){
					super.destroy();
					Properties.currentView = "ReportBuilderView";
					ReportBuilderView reportBuilderView = new ReportBuilderView();
				}
			}
			else
				displayNotLoggedInAlert();
		}
		

		// TODO [ben] comment
		if(e.getActionCommand().equalsIgnoreCase("menuItem_ManageEmployees")
				&& assertPermissionGranted(Permission.MANAGE_EMPLOYEES)){
			if(Properties.isLoggedIn){
				if(displayInformationWillBeLostDialog()){
					super.destroy();
					Properties.currentView = "ManageEmployees";
					EmployeeView generateShiftSchedRptView = new EmployeeView();
				}
			}
			else
				displayNotLoggedInAlert();
		}
		
		// If User Accounts menu item is selected from popup menu
		if(e.getActionCommand().equalsIgnoreCase("menuItem_UserAccounts")
				&& assertPermissionGranted(Permission.ADMINISTER_USERS)){
			if(Properties.isLoggedIn){
				if(displayInformationWillBeLostDialog()){
					super.destroy();
					Properties.currentView = "UserAccountView";
					UserAccountView userAccountView = new UserAccountView();
				}
			}
			else
				displayNotLoggedInAlert();
		}
		
		// TODO [matt] Add in ability to not re-open view if already opened
		// TODO [matt]  Add ability to only access views if you have the given permissions
	}
	
	private void displayNotLoggedInAlert(){
		JOptionPane.showConfirmDialog(null, 
				"You must be logged in to do that!",
				"Not Logged In!",
				JOptionPane.DEFAULT_OPTION,
				JOptionPane.WARNING_MESSAGE);
	}
	
	/**
	 * Handles the events for creating the login dialog. Should just create an instance
	 * of the login dialog local to this method so that it is destroyed when needed.
	 */
	@SuppressWarnings("unused")
	public void createLoginDialog(){
		
		// Create an instance of the Login Dialog Controller which handles both login and logout
		LoginController loginDialog = new LoginController(super.getGUIFrame());
		
	}
	
	private boolean displayInformationWillBeLostDialog(){
		
		// If dialog should be displayed
		if(Properties.informationWillBeLost){

			// Options for buttons
			Object[] options = {"Continue", "Cancel"};
			
			// Show popup to confirm changing views
			int response = JOptionPane.showOptionDialog(null, 
					"There is a possibility that information you have entered will be lost if you continue!",
					"WARNING: INFORMATION MAY BE LOST!",
					JOptionPane.OK_CANCEL_OPTION,
					JOptionPane.PLAIN_MESSAGE,
					null,
					options,
					options[0]);
			
			// If user clicks continue, return true to open new view
			if(response == JOptionPane.YES_OPTION)
				return true;
			// If user clicks cancel, dismiss dialog and do not open new view
			else
				return false;

		}
		// Dialog should not be displayed, so return true so that the new view is displayed
		else
			return true;

	}

	/**
	 * The following mouse events are used for the modules so that right-clicks can be caught and
	 * handled easier. This is not required for most classes because right clicking should not be
	 * a main feature, but in this case it is very useful.
	 */
	
	/**
	 * The mouse clicked is the only event used. It will show the associated popup menu
	 * for each module clicked on (left or right click).
	 */
	@Override
	public void mouseClicked(MouseEvent e) {
		
		JButton reservationModule = super.getGUIFrame().getModuleButtons()[0];
		JButton frontDeskModule = super.getGUIFrame().getModuleButtons()[1];
		JButton roomManagementModule = super.getGUIFrame().getModuleButtons()[2];
		JButton hotelAdminModule = super.getGUIFrame().getModuleButtons()[3];
		JButton userAccountModule = super.getGUIFrame().getModuleButtons()[4];
		
		// If the reservation module button is clicked
		if(e.getComponent().equals(reservationModule)){
			
			// Show the popup menu for the reservation module
			// Called twice so that it can get it's hieght before being displayed properly.
			reservationPopup.show(e.getComponent(), e.getX(), (e.getY() - reservationPopup.getHeight()) );
			reservationPopup.show(e.getComponent(), e.getX(), (e.getY() - reservationPopup.getHeight()) );
			
		}
		
		// If the front desk module button is clicked
		if(e.getComponent().equals(frontDeskModule)){
			
			// Show the popup menu for the front desk module
			// Called twice so that it can get it's hieght before being displayed properly.
			frontDeskPopup.show(e.getComponent(), e.getX(), (e.getY() - frontDeskPopup.getHeight()) );
			frontDeskPopup.show(e.getComponent(), e.getX(), (e.getY() - frontDeskPopup.getHeight()) );
		}
		
		// If the room management module button is clicked
		if(e.getComponent().equals(roomManagementModule)){
			
			// Show the popup menu for the room management module
			// Called twice so that it can get it's hieght before being displayed properly.
			roomManagementPopup.show(e.getComponent(), e.getX(), (e.getY() - roomManagementPopup.getHeight()) );
			roomManagementPopup.show(e.getComponent(), e.getX(), (e.getY() - roomManagementPopup.getHeight()) );
		}
		
		// If the hotel administration module button is clicked
		if(e.getComponent().equals(hotelAdminModule)){
			
			// Show the popup menu for the hotel administration module
			// Called twice so that it can get it's hieght before being displayed properly.
			hotelAdminPopup.show(e.getComponent(), e.getX(), (e.getY() - hotelAdminPopup.getHeight()) );
			hotelAdminPopup.show(e.getComponent(), e.getX(), (e.getY() - hotelAdminPopup.getHeight()) );
			
		}
		
		// If the user accounts module button is clicked
		if(e.getComponent().equals(userAccountModule)){
			
			
			int temp = e.getY() - userAccountPopup.getHeight();
			// Show the popup menu for the user accounts module
			// Called twice so that it can get it's hieght before being displayed properly.
			userAccountPopup.show(e.getComponent(), e.getX(), e.getY() - userAccountPopup.getHeight() );
			userAccountPopup.show(e.getComponent(), e.getX(), e.getY() - userAccountPopup.getHeight() );
			
		}
	}

	@Override
	public void mouseEntered(MouseEvent e) {
		
	}

	@Override
	public void mouseExited(MouseEvent e) {
		
	}

	@Override
	public void mousePressed(MouseEvent e) {
		
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		
	}
}
